package main;

import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.util.ArrayList;

public class MoveUI extends PhaseUI {
	
	public MoveMouse myMouse;
	public ArrayList<Button> moveOptions = new ArrayList<Button>();
	
	public boolean targetingMagic = false;
	public Button spellToCast = null;
	public Unit magicTarget;
	
	public boolean compelMoving = false;
	
	public Panel targetStats;
	
	public Area walkPath = null;
	
	public void beginPhase() {
		targetingMagic = false;
		magicTarget = null;
		
		myUI.targetedUnit = null;
		
		myMouse = new MoveMouse();
		myMouse.myUI = myUI;
		myMouse.myMoveUI = this;
		myUI.addMouseListener(myMouse);
		myUI.addMouseMotionListener(myMouse);
		
		targetStats = myUI.buildStatsPanel("Target", myUI.dim.width-200, myUI.dim.height-280);
		myUI.add(targetStats);
		
		moveOptions = new ArrayList<Button>();
	}
	
	public void endPhase() {
		for (Button b : moveOptions)
			myUI.remove(b);
		
		if (myUI.game.priority != myUI.game.currArmy){
			// Clean up move stuff
			myUI.removeMouseListener(myMouse);
			myUI.removeMouseMotionListener(myMouse);
			
			// None else yet (Possibly once equipment is added there will be)
			myUI.remove(targetStats);
			
			// Create a HeroicShootUI and set it to be the new phase
			HeroicShootUI shootUI = new HeroicShootUI();
			shootUI.myUI = myUI;
			myUI.phaseUI = shootUI;
			myUI.phaseUI.beginPhase();
		}
		else{
			myUI.selectedUnit = null;
			myUI.targetedUnit = null;
			myUI.repaint();
		}
		myUI.game.endPhase();
	}
	
	public void castTargetingSpell() {
		if (spellToCast != null) {
			spellToCast.dispatchEvent(new MouseEvent(spellToCast, MouseEvent.MOUSE_CLICKED, 
					System.currentTimeMillis(), 0, 10, 10, 1, false));
		}
	}

	public void selectUnit(Unit u) {
		myUI.selectedUnit = u;
		
		if (compelMoving)
			return;
		
		// Remove previous buttons
		for (Button b : moveOptions){
			myUI.remove(b);
		}
		
		moveOptions = new ArrayList<Button>();
		
		// Get buttons for new unit, but only if it's in our army (should never happen, so commented out for now to reuse this function in HeroicMove.
		// If issues arise, may need to copy code over into heroic move)
		//if (u.armyIndex != myUI.game.currArmy) 
		//	return;
		int buttonCount = 0;
		// First, check for terrain
		Button terrainInteract = u.getTerrainInteract();
		if (terrainInteract != null && !u.isTransfixed){
			terrainInteract.setBounds(myUI.dim.width-200, 100+55*buttonCount, 80, 50);
			moveOptions.add(terrainInteract);
			myUI.add(terrainInteract);
			buttonCount++;
		}
		// Then check for standing up and laying down
		if (u.layingDown && u.moveLeft >= 0.5) {
			// Make a stand up button
			Button standUp = new Button("Stand up");
			standUp.setBounds(myUI.dim.width-200, 100+55*buttonCount, 80, 50);
			standUp.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					u.standUp();
					myUI.selectUnit(u);
				}
			});
			moveOptions.add(standUp);
			myUI.add(standUp);
			buttonCount++;
		}
		else if (!u.layingDown && u.moveLeft >= u.move / 2) {
			// Make a lay down button
			Button layDown = new Button("Lay down");
			layDown.setBounds(myUI.dim.width-200, 100+55*buttonCount, 80, 50);
			layDown.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					u.layDown();
					myUI.selectUnit(u);
				}
			});
			moveOptions.add(layDown);
			myUI.add(layDown);
			buttonCount++;
		}
		
		// Then for magic
		if (u.battle == null && !u.layingDown && !u.isTransfixed){
			ArrayList<Button> spellButtons = u.getSpellButtons();
			for (Button b : spellButtons) {
				b.setBounds(myUI.dim.width-200, 100+55*buttonCount, 80, 50);
				moveOptions.add(b);
				myUI.add(b);
				buttonCount++;
			}
		}
		
		// Eventually throwing weapons too (or only while charging? recheck this)
	}
	
	public void updateTargetPanel() {
		if (targetStats == null)
			targetStats = myUI.buildStatsPanel("Target", myUI.dim.width-200, myUI.dim.height-280);
		
		if (myUI.targetedUnit != null) {
			((Label)targetStats.getComponent(1)).setText("Move Left: " + String.format("%.2f", myUI.targetedUnit.moveLeft));
			((Label)targetStats.getComponent(2)).setText("Strength: " + myUI.targetedUnit.getStrength());
			((Label)targetStats.getComponent(3)).setText("Defense: " + myUI.targetedUnit.getDefense());
			((Label)targetStats.getComponent(4)).setText("Attacks: " + myUI.targetedUnit.getAttacks());
			((Label)targetStats.getComponent(5)).setText("Wounds: " + myUI.targetedUnit.getWounds());
			((Label)targetStats.getComponent(6)).setText("Courage: " + myUI.targetedUnit.getCourage());
			((Label)targetStats.getComponent(7)).setText("FightValue: " + myUI.targetedUnit.getFightValue());
			((Label)targetStats.getComponent(8)).setText("ShootValue: " + myUI.targetedUnit.getShootValue());
			((Label)targetStats.getComponent(9)).setText("Mt/Wl/Ft: " + myUI.targetedUnit.getMight()+"/"+
													myUI.targetedUnit.getWill()+"/"+myUI.targetedUnit.getFate());
		}
		else {
			((Label)targetStats.getComponent(1)).setText("Move Left: -");
			((Label)targetStats.getComponent(2)).setText("Strength: -");
			((Label)targetStats.getComponent(3)).setText("Defense: -");
			((Label)targetStats.getComponent(4)).setText("Attacks: -");
			((Label)targetStats.getComponent(5)).setText("Wounds: -");
			((Label)targetStats.getComponent(6)).setText("Courage: -");
			((Label)targetStats.getComponent(7)).setText("FightValue: -");
			((Label)targetStats.getComponent(8)).setText("ShootValue: -");
			((Label)targetStats.getComponent(9)).setText("Mt/Wl/Ft: -/-/-");
		}
	}
	
	public void paint(Graphics bufferG) {
    	if (myUI.targetedUnit != null && myUI.targetedUnit.getWounds() > 0){
    		bufferG.setColor(Color.red);
    		bufferG.drawOval(myUI.targetedUnit.x-(myUI.targetedUnit.pixelRadius+1)-myUI.boardOffsetX, 
    							myUI.targetedUnit.y-(myUI.targetedUnit.pixelRadius+1)-myUI.boardOffsetY, 
    							2*(myUI.targetedUnit.pixelRadius+1), 2*(myUI.targetedUnit.pixelRadius+1));
    		bufferG.setColor(Color.black);
    	}
    	
    	// If showing control zones, do so
    	if (myUI.myKey.isKeyDown('c')) {
			AffineTransform offsetShift = AffineTransform.getTranslateInstance(-1*myUI.boardOffsetX, -1*myUI.boardOffsetY);
			Color goodColor = new Color(0, 255, 0, 50);
			bufferG.setColor(goodColor);
			for (Unit u : myUI.game.armies[Game.GOODINDEX].units) {
    			Area goodClone = u.getControlZone();
    			goodClone.transform(offsetShift);
    			((Graphics2D)bufferG).fill(goodClone);
    		}
			Color badColor = new Color(255, 0, 0, 50);
			bufferG.setColor(badColor);
			for (Unit u : myUI.game.armies[Game.BADINDEX].units) {
    			Area badClone = u.getControlZone();
    			badClone.transform(offsetShift);
    			((Graphics2D)bufferG).fill(badClone);
    		}
    	}
    	bufferG.setColor(Color.BLACK);
		updateTargetPanel();
		
		// Debug stuff
		if (walkPath != null)
			((Graphics2D)bufferG).fill(walkPath);
	}
	
}
